<template>
  <div>
    <div class="condition-item">
      <Row :gutter="[16, 8]" :wrap="true">
        <template v-for="(item, index) in curCondition" :key="index">
          <Col :span="7">
            <TreeSelect
              v-model:value="item.lFieldId"
              :tree-data="options"
              :show-search="true"
              tree-node-filter-prop="label"
              :style="{ width: '100%' }"
              @select="methods.onChangeLField(index, $event)"
            />
          </Col>
          <Col :span="7">
            <Select
              v-model:value="item.opType"
              :options="
                methods.returnOptionByDataType(item.lFieldId ?? undefined)
              "
              :style="{ width: '100%' }"
            />
          </Col>
          <Col :span="7">
            <component
              :is="
                methods.returnComByDataType(
                  index,
                  item.lFieldId ?? undefined,
                  item.opType ?? undefined
                )
              "
              :style="{ width: '100%' }"
              v-model:value="item.rOpValueConst"
            />
          </Col>
          <Col :span="3">
            <div class="del-icon" @click="methods.delCondition(index)">
              <MinusCircleOutlined />
            </div>
          </Col>
        </template>
      </Row>
    </div>

    <Button @click="methods.addCondition" type="primary">新增条件</Button>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, ref, watch, h, PropType } from 'vue'
import {
  TreeSelect,
  Select,
  Input,
  Row,
  Col,
  Button,
  InputNumber,
  DatePicker,
  RangePicker,
} from 'ant-design-vue'
import { MinusCircleOutlined } from '@ant-design/icons-vue'
import { BwFilterTableFilterConditionModel } from './model'
import {
  SysDataSetFieldDataTypeEnum,
  SysDataSetDataQueryableItemOpTypeEnum,
  SysDataSetDataAppGetFilterOpValueTypeEnum,
  SysDataSetDataQueryableItemLogicTypeEnum,
  SysDataSetDataQueryableItemTypeEnum,
  SysDataSetDataQueryableItemOpValueDataTypeEnum,
} from '@bitwit/tenantapi'
import {
  optionsToString,
  optionsToNumber,
  optionsToBoolean,
  optionsToStringArr,
  optionsToNumberArr,
  optionsToBooleanArr,
} from './utils'
import RangeNumber from './rangeNumber/index.vue'
import Switch from './switch/index.vue'
import { BwFilterTableTreeListFieldsModel } from '../model'

export default defineComponent({
  name: 'BwDesignFilterTableComFilter',
  components: { TreeSelect, Select, Row, Col, Button, MinusCircleOutlined },
  props: {
    options: {
      type: [Array] as PropType<BwFilterTableTreeListFieldsModel[]>,
    },
    condition: {
      type: [Array] as PropType<BwFilterTableFilterConditionModel[]>,
    },
  },
  emits: ['update:condition'],
  setup(props, { emit }) {
    /** props.options的平铺数据 */
    const tileOptions = computed(() => {
      /** 处理数据 */
      const handleData = (options: Array<BwFilterTableTreeListFieldsModel>) => {
        const _options: Array<BwFilterTableTreeListFieldsModel> = []
        options?.forEach((item) => {
          if (item.children && item.children?.length) {
            _options.push(...handleData(item.children))
          } else {
            _options.push(item)
          }
        })
        return _options
      }
      return handleData(props.options ?? [])
    })

    const curCondition = ref<BwFilterTableFilterConditionModel[]>([])
    watch(
      () => props.condition,
      (newVal) => {
        curCondition.value =
          newVal?.map((item) => ({
            logicType: Number(
              item.logicType ??
                SysDataSetDataQueryableItemLogicTypeEnum.NUMBER_1
            ),
            type: Number(
              item.type ?? SysDataSetDataQueryableItemTypeEnum.NUMBER_1
            ),
            lOpValueType:
              item.lOpValueType ??
              SysDataSetDataAppGetFilterOpValueTypeEnum.NUMBER_4,
            lOpValueDataType:
              item.lOpValueDataType ??
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1,
            lFieldId: item.lFieldId,
            opType: Number(
              item.opType ?? SysDataSetDataQueryableItemOpTypeEnum.NUMBER_1
            ),
            rOpValueType: Number(
              item.rOpValueType ??
                SysDataSetDataAppGetFilterOpValueTypeEnum.NUMBER_1
            ),
            rOpValueConst: item.rOpValueConst,
            rOpValueDataType:
              item.rOpValueDataType ??
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1,
          })) ?? []
        if (!curCondition.value?.length) {
          curCondition.value.push({
            logicType: SysDataSetDataQueryableItemLogicTypeEnum.NUMBER_1,
            type: SysDataSetDataQueryableItemTypeEnum.NUMBER_1,
            lOpValueType: SysDataSetDataAppGetFilterOpValueTypeEnum.NUMBER_4,
            lOpValueDataType:
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1,
            lFieldId: undefined,
            opType: SysDataSetDataQueryableItemOpTypeEnum.NUMBER_1,
            rOpValueType: SysDataSetDataAppGetFilterOpValueTypeEnum.NUMBER_1,
            rOpValueConst: undefined,
            rOpValueDataType:
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1,
          })
        }
      },
      { immediate: true, deep: true }
    )
    watch(
      () => curCondition.value,
      (newVal) => {
        if (JSON.stringify(newVal) !== JSON.stringify(props.condition)) {
          emit('update:condition', newVal)
        }
      },
      { immediate: true, deep: true }
    )

    const methods = {
      returnOptionByDataType: (lFieldId?: string) => {
        const dataType = tileOptions.value?.find(
          (i) => i.value == lFieldId
        )?.dataType
        switch (dataType) {
          case SysDataSetFieldDataTypeEnum.NUMBER_1:
            return optionsToString()
          case SysDataSetFieldDataTypeEnum.NUMBER_2:
            return optionsToNumber()
          case SysDataSetFieldDataTypeEnum.NUMBER_3:
            return optionsToNumber()
          case SysDataSetFieldDataTypeEnum.NUMBER_4:
            return optionsToNumber()
          case SysDataSetFieldDataTypeEnum.NUMBER_6:
            return optionsToBoolean()
          case SysDataSetFieldDataTypeEnum.NUMBER_7:
            return optionsToStringArr()
          case SysDataSetFieldDataTypeEnum.NUMBER_8:
            return optionsToNumberArr()
          case SysDataSetFieldDataTypeEnum.NUMBER_9:
            return optionsToNumberArr()
          case SysDataSetFieldDataTypeEnum.NUMBER_10:
            return optionsToNumberArr()
          case SysDataSetFieldDataTypeEnum.NUMBER_12:
            return optionsToBooleanArr()

          default:
            return optionsToString()
        }
      },
      /** 根据dataType类型返回相应组件 */
      returnComByDataType: (
        index: number,
        lFieldId?: string,
        opType?: SysDataSetDataQueryableItemOpTypeEnum
      ) => {
        const dataType = tileOptions.value?.find(
          (i) => i.value == lFieldId
        )?.dataType
        switch (dataType) {
          case SysDataSetFieldDataTypeEnum.NUMBER_1:
            curCondition.value[index].rOpValueDataType =
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1
            return Input
          case SysDataSetFieldDataTypeEnum.NUMBER_2:
            if (opType == SysDataSetDataQueryableItemOpTypeEnum.NUMBER_14) {
              curCondition.value[index].rOpValueDataType =
                SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_7
              return h(RangePicker, { valueFormat: 'x' })
            } else {
              curCondition.value[index].rOpValueDataType =
                SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_2
              return h(DatePicker, { valueFormat: 'x' })
            }
          case SysDataSetFieldDataTypeEnum.NUMBER_3:
            if (opType == SysDataSetDataQueryableItemOpTypeEnum.NUMBER_14) {
              curCondition.value[index].rOpValueDataType =
                SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_9
              return RangeNumber
            } else {
              curCondition.value[index].rOpValueDataType =
                SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_4
              return InputNumber
            }

          case SysDataSetFieldDataTypeEnum.NUMBER_4:
            if (opType == SysDataSetDataQueryableItemOpTypeEnum.NUMBER_14) {
              curCondition.value[index].rOpValueDataType =
                SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_9
              return RangeNumber
            } else {
              curCondition.value[index].rOpValueDataType =
                SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_4
              return InputNumber
            }
          case SysDataSetFieldDataTypeEnum.NUMBER_6:
            curCondition.value[index].rOpValueDataType =
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_5
            return Switch
          case SysDataSetFieldDataTypeEnum.NUMBER_7:
            curCondition.value[index].rOpValueDataType =
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1
            return Input
          case SysDataSetFieldDataTypeEnum.NUMBER_8:
            curCondition.value[index].rOpValueDataType =
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_2
            return h(DatePicker, { valueFormat: 'x' })
          case SysDataSetFieldDataTypeEnum.NUMBER_9:
            curCondition.value[index].rOpValueDataType =
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_4
            return InputNumber
          case SysDataSetFieldDataTypeEnum.NUMBER_10:
            curCondition.value[index].rOpValueDataType =
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_4
            return InputNumber
          case SysDataSetFieldDataTypeEnum.NUMBER_12:
            curCondition.value[index].rOpValueDataType =
              SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_5
            return Switch

          default:
            return Input
        }
      },
      /** 添加条件 */
      addCondition: () => {
        curCondition.value.push({
          logicType: SysDataSetDataQueryableItemLogicTypeEnum.NUMBER_1,
          type: SysDataSetDataQueryableItemTypeEnum.NUMBER_1,
          lOpValueType: SysDataSetDataAppGetFilterOpValueTypeEnum.NUMBER_4,
          lOpValueDataType:
            SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1,
          lFieldId: '',
          opType: SysDataSetDataQueryableItemOpTypeEnum.NUMBER_1,
          rOpValueType: SysDataSetDataAppGetFilterOpValueTypeEnum.NUMBER_1,
          rOpValueConst: undefined,
          rOpValueDataType:
            SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1,
        })
      },
      /** 删除条件 */
      delCondition: (index: number) => {
        curCondition.value.splice(index, 1)
      },
      /** 改变左侧字段时触发 */
      onChangeLField: (index: number, value: string) => {
        const item = curCondition.value[index]
        item.opType = undefined
        item.rOpValueConst = undefined
        item.lOpValueDataType = methods.getOpValueDataType(
          tileOptions.value?.find((i) => i.value == value)?.dataType
        )
      },
      /** 枚举转换 */
      getOpValueDataType(
        dataType?: SysDataSetFieldDataTypeEnum
      ): SysDataSetDataQueryableItemOpValueDataTypeEnum {
        switch (dataType) {
          case SysDataSetFieldDataTypeEnum.NUMBER_1:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1
          case SysDataSetFieldDataTypeEnum.NUMBER_2:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_2
          case SysDataSetFieldDataTypeEnum.NUMBER_3:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_3
          case SysDataSetFieldDataTypeEnum.NUMBER_4:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_4
          case SysDataSetFieldDataTypeEnum.NUMBER_6:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_5
          case SysDataSetFieldDataTypeEnum.NUMBER_7:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_6
          case SysDataSetFieldDataTypeEnum.NUMBER_8:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_7
          case SysDataSetFieldDataTypeEnum.NUMBER_9:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_8
          case SysDataSetFieldDataTypeEnum.NUMBER_10:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_9
          case SysDataSetFieldDataTypeEnum.NUMBER_12:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_10
          default:
            return SysDataSetDataQueryableItemOpValueDataTypeEnum.NUMBER_1
        }
      },
    }

    return { curCondition, methods }
  },
})
</script>

<style lang="less" scoped>
.condition-item {
  overflow: hidden;
  margin-bottom: 12px;
}

.del-icon {
  height: 100%;
  font-size: 20px;
  color: red;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}
</style>
